
package com.hzg.springcloud.controller;

import com.hzg.springcloud.Order;
import com.hzg.springcloud.service.IOrderService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/orders")
@Slf4j
public class OrderController {
    @Autowired
    private IOrderService orderService;
    //降级配置,一旦这个方法异常或者,超时,走fallbackMethod这个指定的降级方法
    @HystrixCommand(fallbackMethod = "saveFallback")
    @GetMapping("/save/{userId}/{productId}")//restFul风格插入的时候是postMapping的为插入,但是现在为了方便测试使用GETMapping
    public Order save(@PathVariable Long userId, @PathVariable Long productId, HttpServletRequest request){

        //System.out.println("OrderController.....save....");
        log.info("OrderController.....save....");
        String cookie = request.getHeader("Cookie");
        String token = request.getHeader("token");
        System.out.println(cookie+"--------------------"+token);
        //当传输过来的用户id小于0 的时候才会执行降级操作
      /*  if (userId<0){
            int i=1/0;
        }*/
        Order order = orderService.save(userId, productId);
        //return new Order();
        return order;
    }

    //方法签名跟接口一样  就是除了里面的执行代码块不一样,其他的都要一样
    //并且该方法名称要和上面指定的(fallbackMethod = "saveFallback")  一样
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    public Order saveFallback(@PathVariable Long userId,@PathVariable Long productId, HttpServletRequest reques){
        System.out.println("走降级方法....");
        //后期要做的操作
        //通知运维人员或者程序员赶紧过来修复
        //发短信或者发邮件
        //redis限制频率
        //启动一个线程,让线程执行发送短信逻辑
        new Thread(()->{//主线程专门做降级返回的操作,该线程专门做短信的回复,防止短信的发送出现问题,影响降级的操作
            String redisKey = "order-save";
            String value = stringRedisTemplate.opsForValue().get(redisKey);
            if(StringUtils.isEmpty(value)){
                System.out.println("order下订单服务失败，请查找原因.");
                //int i=1/0;//模拟报错
                stringRedisTemplate.opsForValue().set(redisKey,"save-order-fail",20, TimeUnit.SECONDS);
            }else{
                System.out.println("已经发送过短信");
            }
        }).start();
        return new Order() ;
    }
}